#include <semaphore.h>

#include "Thread.h"
#include "CurrentThread.h"

namespace Logger
{
    std::atomic_int Thread::sThreadNum = 0;

    Thread::Thread(ThreadFunc func, const std::string &name)
        : func_(std::move(func)), name_(name),
          isStart_(false), isJoin_(false),
          tid_(0)
    {
        this->initDefaultName();
    }

    Thread::~Thread()
    {
        if (this->isStart_ && !this->isJoin_)
        {
            this->thread_->detach(); // 没有join()就detach()后台异步销毁
        }
    }

    void Thread::initDefaultName()
    {
        int num = ++sThreadNum;
        if (this->name_.empty())
        {
            this->name_ = "Thread" + std::to_string(num);
        }
    }

    void Thread::start() // 一个Thread对象 记录的就是一个新线程的详细信息
    {
        this->isStart_ = true;

        // C++20才有信号量API，系统调用信号量同步获取 编译器指令优化获取的缓存线程标识 避免线程不安全
        sem_t sem{};
        ::sem_init(&sem, false, 0); // false不设置进程间共享
        // 先初始化Thread，合适时机才启动线程
        // 线程创建时再绑定tid
        this->thread_ = std::shared_ptr<std::thread>(
            new std::thread([&]()
                            {
                                this->tid_ = Logger::getTid();
                                ::sem_post(&sem);
                                this->func_(); }));
        ::sem_wait(&sem);
    }

    void Thread::join()
    {
        this->isJoin_ = true;
        this->thread_->join();
    }
} // namespace Logger
